/**   
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-12-07 13:44:19  
 * Copyright (c) 2015- joysuch-版权所有     
 */

package com.joysuch.wwyt.bp.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import javax.transaction.Transactional;

import com.joysuch.wwyt.bp.bean.BpEmergencyMaterialDetailBean;
import com.joysuch.wwyt.bp.bean.BpEmergencyMaterialEditBean;
import com.joysuch.wwyt.bp.bean.BpEmergencyMaterialListBean;
import com.joysuch.wwyt.bp.bean.BpEmergencyMaterialListBean.Search;
import com.joysuch.wwyt.bp.entity.BpEmergencyMaterial;
import com.joysuch.wwyt.bp.entity.BpEmergencyMaterialType;
import com.joysuch.wwyt.bp.entity.dsl.QBpEmergencyMaterial;
import com.joysuch.wwyt.bp.entity.dsl.QBpStoreHouse;
import com.joysuch.wwyt.bp.repository.BpEmergencyMaterialDao;
import com.joysuch.wwyt.bp.repository.BpStoreHouseDao;
import com.joysuch.wwyt.bp.service.BpEmergencyMaterialService;
import com.joysuch.wwyt.bp.service.BpEmergencyMaterialTypeService;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.PageDataUtils.PageDataConvert;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

@Service
@Transactional
public class BpEmergencyMaterialServiceImpl implements BpEmergencyMaterialService {

    @Autowired
    private BpEmergencyMaterialDao dao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    @Autowired
    private BpStoreHouseDao bpStoreHouseDao;

    @Autowired
    private BpEmergencyMaterialTypeService bpEmergencyMaterialTypeService;

    @Override
    public BpEmergencyMaterial add(BpEmergencyMaterialEditBean entity) throws Exception {
        BpEmergencyMaterial content = new BpEmergencyMaterial();
        // 物资名称
        content.setName(entity.getName());
        // 物资编号
        content.setCode(bizCodeGeneratorFacade.wuzi());
        // 物资型号
        content.setMaterialModel(entity.getMaterialModel());
        // 数量
        content.setMaterialNumber(entity.getMaterialNumber());
        // 存放地点ID
        content.setStorageLocationId(entity.getStorageLocationId());
        // 保存状态 约定（1.完好；2.维修中）
        if (entity.getState() != null && !"".equals(entity.getState())) {
            content.setState(entity.getState());
        }

        // 物资类型ID
        content.setMaterialTypeId(entity.getMaterialTypeId());
        // 用途
        content.setPurpose(entity.getPurpose());
        // 生产日期
        content.setManufactureTime(entity.getManufactureTime());
        // 到期日期
        content.setExpireTime(entity.getExpireTime());
        // 购入日期
        content.setPayTime(entity.getPayTime());
        // 投用日期
        content.setUseTime(entity.getUseTime());
        // 制造厂家
        content.setManufacturer(entity.getManufacturer());
        // 所属单位
        content.setSubordinateUnits(entity.getSubordinateUnits());
        // 是否可回收（0:是，1:否）
        content.setIsRecyclable(entity.getIsRecyclable());
        // 备注
        content.setRemark(entity.getRemark());
        dao.save(content);
        // 更新物资对应类型的数量
        bpEmergencyMaterialTypeService.updateMaterialCount(content.getMaterialTypeId());
        return content;
    }

    @Override
    public void update(BpEmergencyMaterialEditBean entity) throws Exception {
        BpEmergencyMaterial content = dao.findById(entity.getId()).get();
        Long oldTypeId = content.getMaterialTypeId();
        Long newTypeId = entity.getMaterialTypeId();
        // ID，主键
        content.setId(entity.getId());
        // 物资名称
        content.setName(entity.getName());
        // 物资型号
        content.setMaterialModel(entity.getMaterialModel());
        // 数量
        content.setMaterialNumber(entity.getMaterialNumber());
        // 存放地点ID
        content.setStorageLocationId(entity.getStorageLocationId());
        // 保存状态 约定（1.完好；2.维修中）
        content.setState(entity.getState());
        // 物资类型ID
        content.setMaterialTypeId(entity.getMaterialTypeId());
        // 用途
        content.setPurpose(entity.getPurpose());
        // 生产日期
        content.setManufactureTime(entity.getManufactureTime());
        // 到期日期
        content.setExpireTime(entity.getExpireTime());
        // 购入日期
        content.setPayTime(entity.getPayTime());
        // 投用日期
        content.setUseTime(entity.getUseTime());
        // 制造厂家
        content.setManufacturer(entity.getManufacturer());
        // 所属单位
        content.setSubordinateUnits(entity.getSubordinateUnits());
        // 是否可回收（0:是，1:否）
        content.setIsRecyclable(entity.getIsRecyclable());
        // 备注
        content.setRemark(entity.getRemark());
        dao.save(content);
        if (!Objects.equals(oldTypeId, newTypeId)) {
            bpEmergencyMaterialTypeService.updateMaterialCount(newTypeId);
            bpEmergencyMaterialTypeService.updateMaterialCount(oldTypeId);
        }
    }

    @Override
    public Page<BpEmergencyMaterialListBean> findByPage(Pageable page, Search condition) {
        Predicate predicate = prepareListSearchCondition(condition);
        page = PageDataUtils.addOrderByDesc(page, "id");
        Page<BpEmergencyMaterial> data = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);

        return PageDataUtils.convertPageData(data,
                new PageDataConvert<BpEmergencyMaterialListBean, BpEmergencyMaterial>() {

                    @Override
                    public BpEmergencyMaterialListBean convert(BpEmergencyMaterial f) {
                        BpEmergencyMaterialListBean bean = new BpEmergencyMaterialListBean();

                        // ID，主键
                        bean.setId(f.getId());
                        // 物资名称
                        bean.setName(f.getName());
                        // 物资编号
                        bean.setCode(f.getCode());
                        // 物资型号
                        bean.setMaterialModel(f.getMaterialModel());
                        // 数量
                        bean.setMaterialNumber(f.getMaterialNumber());
                        // 存放地点ID
                        bean.setStorageLocationId(f.getStorageLocationId());
                        // 存放地点名称
                        if (f.getStorageLocationId() != null) {
                            bpStoreHouseDao.findById(f.getStorageLocationId())
                                    .ifPresent(house -> bean.setStorageLocationName(house.getName()));
                        }
                        // 保存状态
                        if (f.getState() != null) {
                            bean.setState(f.getState());
                            if (f.getState() == 0) {
                                bean.setStateName("维修中");
                            } else if (f.getState() == 1) {
                                bean.setStateName("完好");
                            }
                        }

                        // 保存状态名称，约定（1.完好；2.维修中）暂时不传名称
                        // bean.setStateName("");
                        // 物资类型ID
                        bean.setMaterialTypeId(f.getMaterialTypeId());
                        // 物资类型名称
                        if (f.getMaterialTypeId() != null) {
                            BpEmergencyMaterialType mType = bpEmergencyMaterialTypeService
                                    .findById(f.getMaterialTypeId());
                            if (mType != null) {
                                bean.setMaterialTypeName(mType.getName());
                            }
                        }
                        // 用途
                        bean.setPurpose(f.getPurpose());
                        // 生产日期
                        bean.setManufactureTime(f.getManufactureTime() == null ? null
                                : SimpleDateFormatCache.getYmdhms().format(f.getManufactureTime()));
                        // 到期日期
                        bean.setExpireTime(f.getExpireTime() == null ? null
                                : SimpleDateFormatCache.getYmdhms().format(f.getExpireTime()));
                        // 购入日期
                        bean.setPayTime(f.getPayTime() == null ? null
                                : SimpleDateFormatCache.getYmdhms().format(f.getPayTime()));
                        // 投用日期
                        bean.setUseTime(f.getUseTime() == null ? null
                                : SimpleDateFormatCache.getYmdhms().format(f.getUseTime()));
                        // 制造厂家
                        bean.setManufacturer(f.getManufacturer());
                        // 所属单位
                        bean.setSubordinateUnits(f.getSubordinateUnits());
                        // 是否可回收（0:是，1:否）
                        bean.setIsRecyclable(f.getIsRecyclable());
                        // 备注
                        bean.setRemark(f.getRemark());

                        return bean;
                    }

                });
    }

    private Predicate prepareListSearchCondition(Search condition) {
        QBpEmergencyMaterial qEmeMaterial = QBpEmergencyMaterial.bpEmergencyMaterial;
        Predicate predicate = null;
        if (condition.getName() != null) {
            predicate = qEmeMaterial.name.like("%" + condition.getName() + "%");
        }
        if (condition.getStorageLocation() != null) {
            // 通过BpStoreHouseDao模糊查询对应 id 列表
            QBpStoreHouse qBpStoreHouse = QBpStoreHouse.bpStoreHouse;
            Predicate pre = qBpStoreHouse.name.like("%" + condition.getStorageLocation() + "%");
            List<Long> ids = new ArrayList<>();
            bpStoreHouseDao.findAll(pre).forEach(t -> {
                ids.add(t.getId());
            });
            BooleanExpression in = qEmeMaterial.storageLocationId.in(ids);
            predicate = predicate == null ? in : ExpressionUtils.and(predicate, in);
        }
        return predicate;
    }

    @Override
    public void delete(Long id) {
        // 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用。不能删除时将抛出业务异常

        BpEmergencyMaterial content = dao.findById(id).get();
        checkBussinessRestrictions(id);
        dao.deleteById(id);
        // 更新物资对应类型的数量
        bpEmergencyMaterialTypeService.updateMaterialCount(content.getMaterialTypeId());
    }

    /**
     * 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用
     * @param id 要删除的业务ID
     * @throws
     */
    private void checkBussinessRestrictions(Long id) {

    }

    @Override
    public BpEmergencyMaterial findById(Long id) {
        return dao.findById(id).get();
    }

    @Override
    public BpEmergencyMaterialDetailBean getById(Long id) {
        BpEmergencyMaterial entity = findById(id);
        BpEmergencyMaterialDetailBean bean = new BpEmergencyMaterialDetailBean();
        // ID，主键
        bean.setId(entity.getId());

        // 物资名称
        bean.setName(entity.getName());

        // 物资编号
        bean.setCode(entity.getCode());

        // 物资型号
        bean.setMaterialModel(entity.getMaterialModel());

        // 数量
        bean.setMaterialNumber(entity.getMaterialNumber());

        // 存放地点ID
        bean.setStorageLocationId(entity.getStorageLocationId());
        // bean.setStorageLocationName(entity.getStorageLocationName());

        // 保存状态
        bean.setState(entity.getState());

        // 物资类型ID
        bean.setMaterialTypeId(entity.getMaterialTypeId());
        // bean.setMaterialTypeName(entity.getMaterialTypeName());

        // 用途
        bean.setPurpose(entity.getPurpose());

        // 生产日期
        bean.setManufactureTime(SimpleDateFormatCache.getYmdhms().format(entity.getManufactureTime()));

        // 到期日期
        bean.setExpireTime(SimpleDateFormatCache.getYmdhms().format(entity.getExpireTime()));

        // 购入日期
        bean.setPayTime(SimpleDateFormatCache.getYmdhms().format(entity.getPayTime()));

        // 投用日期
        bean.setUseTime(SimpleDateFormatCache.getYmdhms().format(entity.getUseTime()));

        // 制造厂家
        bean.setManufacturer(entity.getManufacturer());

        // 所属单位
        bean.setSubordinateUnits(entity.getSubordinateUnits());

        // 是否可回收（0:是，1:否）
        bean.setIsRecyclable(entity.getIsRecyclable());

        // 备注
        bean.setRemark(entity.getRemark());

        return bean;
    }

}
